/*
*
* 版权所有 Copyleft(c) 2005
* 刘炯个人工作室 Sharp-Mark Personal Studio
*
* 允许自由使用，复制，修改，传播和贩卖此源程序及其文档，而不必支付任何费用。
* 以上的版权信息必须出现在每一份复制品中。同时这份版权信息和许可声明
* 也必须出现在支持文档中。刘炯个人工作室不对此软件适于那种具体
* 用途做出任何阐述。此代码只作为代码本身提供对其品质不做任何保证。
*
*/

#include "../Utilities/Matrix.h"
#include "../Line/Line.h"
#include "../Hidden/Hidden.h"

// 立方体类
template<class T>
class CCube
{
public:
	CCube(T l = 200, COLORREF color = RGB(0, 0, 0)) : _length(l), _color(color)
	{
		l /= 2;
		_targetVertices[0] = _cubeVertices[0] = CVec4<T>(l, -l, l, 1);
		_targetVertices[1] = _cubeVertices[1] = CVec4<T>(-l, l, l, 1);
		_targetVertices[2] = _cubeVertices[2] = CVec4<T>(l, l, -l, 1);
		_targetVertices[3] = _cubeVertices[3] = CVec4<T>(-l, -l, -l, 1);
		_targetVertices[4] = _cubeVertices[4] = CVec4<T>(l, l, l, 1);
		_targetVertices[5] = _cubeVertices[5] = CVec4<T>(-l, -l, l, 1);
		_targetVertices[6] = _cubeVertices[6] = CVec4<T>(l, -l, -l, 1);
		_targetVertices[7] = _cubeVertices[7] = CVec4<T>(-l, l, -l, 1);
	}
	~CCube(){}

	void DrawCube(					// 绘制矩形
		CPaintDC& dc,				// 设备上下文
		CMatrix<T>& origin,			// 坐标系转化矩阵
		T distance)					// 投影中心到原点的距离
	{
		ChangeCoordinates(origin);	// 坐标轴转化

		ProjectVerties(distance);	// 物体投影为2D

		ViewToWindows();			// 观察坐标转化到窗体坐标

		int index[] = {4, 5, 6, 0};	// 技巧，用与绘制矩形

		for (int i = 0; i < 4; i++)
		{
			index[3 - i]++;
			for (int j = 0; j < 3; j++)
			{
				BresenhamLine_Sharpmark(
					static_cast<int>(_targetVertices[i].x()),
					static_cast<int>(_targetVertices[i].y()),
					static_cast<int>(_targetVertices[index[j]].x()),
					static_cast<int>(_targetVertices[index[j]].y()),
					_color,
					dc
					);
			}
		}
	}

	// 矩形旋转
	void Rotate(T xangel, T yangel, T zangel)
	{
		for (int i = 0; i < 8; i++)
		{
			_targetVertices[i] = _cubeVertices[i];
			_targetVertices[i].XRotate(xangel);			// 延X轴旋转
			_targetVertices[i].YRotate(yangel);			// 延Y轴旋转
			_targetVertices[i].ZRotate(zangel);			// 延Z轴旋转
		}
	}

	// 坐标轴转化， 从物体坐标转化为观察坐标
	// origin 是两坐标轴之间的关系矩阵
	void ChangeCoordinates(CMatrix<T>& origin)
	{
		for (int i = 0; i < 8; i++)
		{
			_targetVertices[i] = origin * _targetVertices[i];
		}
	}

	// 观察坐标转化到窗体坐标
	void ViewToWindows()
	{
		for (int i = 0; i < 8; i++)
		{
			_targetVertices[i].Translate(_length / 2, _length / 2, 0);
		}
	}

	// 物体投影为2D
	void ProjectVerties(T d)
	{
		CMatrix<T> rotate;
		rotate.SetProjections(d);

		for(int i = 0; i < 8; i++)
		{
			_targetVertices[i] = rotate * _targetVertices[i];
			_targetVertices[i].DivideByW();		// 化为标准坐标
		}
	}

	COLORREF& Color()		// 立方体颜色
	{
		return _color;
	}

	//CPolygon* ReturnPolygons()
	//{
	//	CPolygon polygons[6];
	//	return polygons;
	//}

private:

	CVec4<T> _cubeVertices[8];					// 物体顶点坐标
	CVec4<T> _targetVertices[8];				// 转化后的顶点坐标

	COLORREF _color;							// 立方体颜色

	T _length;									// 立方体边长
};